package com.itbooking.web.weixin;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.itbooking.core.pay.ReportReqData;
import com.itbooking.core.pay.request.QrCodeRequest;
import com.itbooking.core.pay.util.RandomStringGenerator;
import com.itbooking.core.threalLocal.UserThreadLocal;
import com.itbooking.mapper.ProductMapper;
import com.itbooking.pojo.OrderDo;
import com.itbooking.pojo.ProductDo;
import com.itbooking.pojo.UserDo;
import com.itbooking.service.pay.IPayService;
import com.itbooking.service.product.IProductService;
import com.itbooking.vo.OrderVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.function.ServerResponse;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;

@RestController
@RequestMapping("/api/pay")
@Log4j2
public class WeixinPayController {


    // 小程序的APPID
    private final String APPID = "wx2f823cdc8dfba815";
    // 微信支付的私key
    private final String SCRETKEY = "eeacab5be0273e3a6de4e8d48a042c98";
    // 商户号
    private final String MCHID = "1370687602";

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private IPayService payService;

    /***
     * 支付接口地址：https://api.mch.weixin.qq.com/pay/unifiedorder?appid=1222&productid=234

     * @param request--token
     * @return
     */
    @GetMapping("weixin")
    public Map<String, String> payVip(HttpServletRequest request) {
        log.info("微信支付进来了.......");
        //生成订单号

        //1：获取要支付的产品id
        String productid = request.getParameter("productid");
        if (StringUtils.isEmpty(productid)) {
            //这里后续会封装一个统一返回处理
            return null;
        }

        ProductDo productDo = productMapper.selectById(new Long(productid));
        if(productDo==null){
            //这里后续会封装一个统一返回处理
            return null;
        }

        double tprice = productDo.getTprice()==null?0:productDo.getTprice().doubleValue();
        if(tprice<=0){
            //这里后续会封装一个统一返回处理 价格有误
            return null;
        }

        //设置订单编号
        String ordernumber = request.getParameter("ordernumber");
        String orderNo = StringUtils.isEmpty(ordernumber)?System.currentTimeMillis()+"":ordernumber;

        String ip = "127.0.0.1";
        //1：支付得用户信息一定是后端获取，不是前端传递
        UserDo userDo = UserThreadLocal.get();
        Long userId = userDo.getId();
        String openid = userDo.getOpenid();
        String money = String.valueOf(productDo.getTprice());
        log.info("1--------微信支付-------支付得用户是：{}，openid:{}",userId,openid);

        //支付的开始
        // 组装微信支付所需要的参数数据ReportReqData
        ReportReqData data = new ReportReqData();
        //1:支付的APPID（小程序的appid）
        data.setAppid(APPID);
        //2：商户号
        data.setMch_id(MCHID);
        //3：支付的openid
        data.setOpenid(openid);// wx.login(code)-----服务端的接口----openid---token
        //4：支付的内容
        data.setBody(productDo.getTitle());//套餐名称
        //5:支付的流水号
        data.setOut_trade_no(orderNo);//订单号
        //6: 支付的产品ID
        data.setProduct_id(orderNo);//商品ID
        //7:支付的品牌类型注意这里不要写错了JSAPI
        data.setTrade_type("JSAPI");
        //8: 支付需要的ip地址
        data.setSpbill_create_ip(ip);//ip地址
        //9：支付金额 分
        data.setTotal_fee(getMoney(money));//金额
        //10: 这里必须要有32位的随机串，它是一个类似token东西，如果在支付过程发现重复支付就因为你这个相同了
        data.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
        //11：设置支付的异步通知
        data.setNotify_url("https://api.itbooking.net/api/pay/callback");
        //13：设置支付的附加参数，这个附加是放入attach中的，它左右就是在支付的成功以后可以吧这部分参数携带到

        // 异步通知的方法中进行去下单处理
        JSONObject json = new JSONObject();
        json.put("userId", userId.toString());
        json.put("productid",productid);
        json.put("ordernumber",orderNo);
        //创建订单
        String params = json.toString().replace("\"", "'");
        //13: 设置额外的支付参数，作用：用于会支付成功以后的回调使用
        data.setAttach(params);
        log.info("2------微信支付------支付得参数是：{}",data.toMap());

        //微信支付返回的结果
        return QrCodeRequest.submitWeixinMessage(data, SCRETKEY);
    }



    // 微信消息队列----callabck --4-5---钱收到---success/callback----
    // ---订单日记 --管理 -- es -
    // 人工处理----查看日记 --- order----微信
    @RequestMapping("callback")
    public String callback(HttpServletRequest request){
        log.info("1---------------->异步支付回调进来了,开始解析请求头");
        InputStream is = null;
        String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ";
        try {
            is = request.getInputStream();
            // 将InputStream转换成String
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            log.info("微信支付解析完毕,解析出的参数为: " + sb.toString());
            Map<String, String> map = WXPayUtil.xmlToMap(sb.toString());

            System.out.println(map.get("userId"));
            System.out.println(map.get("productid"));
            System.out.println(map.get("ordernumber"));

            //根据ordernumber做幂等性
            //orderMapper.queryByOrderNumber();

        } catch (Exception e) {
            System.out.println("微信手机支付回调通知失败：" + e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";
    }


    /**
     * * 参数1：ordernumber
     * 参数2：productid
     * 支付成功的方法
     * @param orderVo
     * @return
     */
    @PostMapping("paysuccess")
    public OrderDo paySuccess(OrderVo orderVo){
        log.info("1-----paySuccess----支付成功进来了....参数是:{}",orderVo);
        //4:支付的状态 2 代表成功
        orderVo.setStatus(2);
        // 重复订单 根据ordernumber查询一次
        OrderDo orderDo = payService.mainPayOperator(orderVo);
        log.info("2----paySuccess----订单保存成功,订单的编号是：{},保存的订单id是:{}",orderDo.getOrdernumber(), orderDo.getId());
        return orderDo;
    }

    /**
     * 参数1：ordernumber
     * 参数2：productid
     * 支付失败的方法
     * @param orderVo
     * @return
     */
    @PostMapping("payfail")
    public OrderDo payfail(OrderVo orderVo){
        log.info("1-----payfail----支付失败进来了....参数是:{}",orderVo);
        //4:支付的状态 2 代表成功
        orderVo.setStatus(1);
        // 重复订单 根据ordernumber查询一次
        OrderDo orderDo = payService.mainPayOperator(orderVo);
        log.info("2-----payfail-----订单失败保存成功,订单的编号是：{},保存的订单id是:{}",orderDo.getOrdernumber(), orderDo.getId());
        return orderDo;
    }



    /**
     * 元转换成分
     * 微信支付中：100 ---
     *
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if (amount == null) {
            return "";
        }
        // 金额转化为分为单位
        // 处理包含, ￥ 或者$的金额
        String currency = amount.replaceAll("\\$|\\￥|\\,", "");
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0L;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }
}
